﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using Marbles.Core.Content.Sites;

namespace Marbles.Core.Content.Forms
{
    public class UserForm : ICollection<Question>
    {
        public string VirtualPath { get { return string.Format("/App_Data/Forms/{0}/{1}.xml", _web.SiteName, _name); } }
        public string ApplicationPath { get { return HttpContext.Current.Server.MapPath(VirtualPath); } }
        public string Name { get { return _name; } }
        public string Title { get { return GetFormTitle(); } set { SetFormTitle(value); } }
        public string EmailSubject { get { return GetEmailSubject(); } set { SetEmailSubject(value); } }
        public string MailTo { get { return GetFormMailTo(); } set { SetFormMailTo(value); } }
        public bool StoreInDatabase { get { return GetStoreInDatabase(); } set { SetStoreInDatabase(value); } }
        public bool SendEmail { get { return GetSendEmail(); } set { SetSendEmail(value); } }
        public Question[] Questions { get { return GetQuestions().ToArray(); } }
        public Question this[string id] { get { return GetQuestionById(id); } }
        public int Count { get { return Questions.Length; } }
        public bool IsReadOnly { get { return false; } }
        public string SiteId { get { return _web.SiteId; } }

        private XmlDocument xdoc = null;
        private SiteDefinition _web = null;
        private string _name = string.Empty;

        public UserForm(SiteDefinition Web, string Name)
            : this()
        {
            _name = Name;
            _web = Web;
            xdoc = new XmlDocument();
            LoadXml();
        }

        public UserForm(string Name)
            : this()
        {
            _name = Name;
            _web = SiteDefinition.GetCurrent();
            LoadXml();
        }

        public UserForm()
        {
            _name = string.Empty;
            _web = null;
            xdoc = new XmlDocument();
            CreateStructure();
        }

        private void CreateStructure()
        {
            XmlNode nForm = xdoc.CreateElement("form");
            XmlNode nTitle = xdoc.CreateElement("title");
            XmlNode nEmailSubject = xdoc.CreateElement("emailsubject");
            XmlNode nMailTo = xdoc.CreateElement("mailto");
            XmlNode nDB = xdoc.CreateElement("storeindatabase");
            XmlNode nSendMail = xdoc.CreateElement("sendemail");
            XmlNode nQuestions = xdoc.CreateElement("questions");

            nTitle.InnerText = "";
            nEmailSubject.InnerText = "";
            nMailTo.InnerText = "";
            nDB.InnerText = "false";
            nSendMail.InnerText = "false";
            nForm.AppendChild(nTitle);
            nForm.AppendChild(nEmailSubject);
            nForm.AppendChild(nMailTo);
            nForm.AppendChild(nDB);
            nForm.AppendChild(nSendMail);
            nForm.AppendChild(nQuestions);
            xdoc.AppendChild(nForm);
        }

        public void LoadXml()
        {
            if (!File.Exists(ApplicationPath)) { return; }

            FileStream fs = new FileStream(ApplicationPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            xdoc.Load(fs);
            fs.Flush();
            fs.Close();

        }

        public static UserForm CreateNew(SiteDefinition Web, string Name)
        {
            UserForm frm = new UserForm();
            frm._web = Web;
            frm._name = Name;
            return frm;
        }

        public void Save()
        {
            FileStream fs = new FileStream(ApplicationPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
            xdoc.Save(fs);
            fs.Flush();
            fs.Close();
        }

        public void Delete()
        {
            if (File.Exists(ApplicationPath)) { File.Delete(ApplicationPath); }
        }

        private string GetFormMailTo()
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("mailto");
            if (nodes.Count > 0)
            {
                return nodes[0].InnerText;
            }

            return string.Empty;
        }

        private void SetFormMailTo(string value)
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("mailto");
            if (nodes.Count > 0)
            {
                nodes[0].InnerText = value;
            }
        }


        private bool GetStoreInDatabase()
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("storeindatabase");
            if (nodes.Count > 0)
            {
                return Convert.ToBoolean(nodes[0].InnerText.ToLower());
            }

            return false;
        }

        private void SetStoreInDatabase(bool value)
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("storeindatabase");
            if (nodes.Count > 0)
            {
                nodes[0].InnerText = value.ToString().ToLower();
            }
        }

        private bool GetSendEmail()
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("sendemail");
            if (nodes.Count > 0)
            {
                return Convert.ToBoolean(nodes[0].InnerText.ToLower());
            }

            return false;
        }

        private void SetSendEmail(bool value)
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("sendemail");
            if (nodes.Count > 0)
            {
                nodes[0].InnerText = value.ToString().ToLower();
            }
        }
        private string GetFormTitle()
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("title");
            if (nodes.Count > 0)
            {
                return nodes[0].InnerText;
            }

            return string.Empty;
        }

        private void SetFormTitle(string title)
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("title");
            if (nodes.Count > 0)
            {
                nodes[0].InnerText = title;
            }

        }

        private string GetEmailSubject()
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("emailsubject");
            if (nodes.Count > 0)
            {
                return nodes[0].InnerText;
            }

            return string.Empty;
        }

        private void SetEmailSubject(string title)
        {
            XmlNodeList nodes = xdoc.GetElementsByTagName("emailsubject");
            if (nodes.Count > 0)
            {
                nodes[0].InnerText = title;
            }

        }
        private Question GetQuestionById(string id)
        {
            List<Question> items = GetQuestions();
            foreach (Question q in items)
            {
                if (q.Id == id) { return q; }
            }
            return null;
        }

        private List<Question> GetQuestions()
        {
            List<Question> items = new List<Question>();
            XmlNodeList list = xdoc.GetElementsByTagName("question");

            foreach (XmlNode node in list)
            {
                items.Add(new Question(xdoc, node));
            }

            return items;
        }

        public void Add(Question Question)
        {
            XmlNodeList list = xdoc.GetElementsByTagName("questions");
            if (list.Count > 0)
            {
                list[0].AppendChild(Question.InnerNode);
            }
        }

        public void Clear()
        {
            XmlNodeList list = xdoc.GetElementsByTagName("questions");
            if (list.Count > 0)
            {
                list[0].RemoveAll();
            }

        }

        public bool Contains(Question item)
        {
            return GetQuestions().Contains(item);
        }

        public void CopyTo(Question[] array, int arrayIndex)
        {
            GetQuestions().CopyTo(array, arrayIndex);
        }

        public bool Remove(Question item)
        {
            XmlNodeList list = xdoc.GetElementsByTagName("questions");

            if (list.Count > 0)
            {
                list[0].RemoveChild(item.InnerNode);
                return true;
            }

            return false;
        }

        public IEnumerator<Question> GetEnumerator()
        {
            return GetQuestions().GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetQuestions().GetEnumerator();
        }
    }
}